@@ -21,6 +21,10 @@ |
||
21 | 21 |
<!-- your app's js --> |
22 | 22 |
<script src="js/app.js"></script> |
23 | 23 |
<script src="js/controllers.js"></script> |
24 |
+ <script src="js/controllers/login-ctrl.js"></script> |
|
25 |
+ <script src="js/services/data-service.js"></script> |
|
26 |
+ <script src="js/services/oauth-service.js"></script> |
|
27 |
+ <script src="js/services/realtime-service.js"></script> |
|
24 | 28 |
<script src="js/missionData.js"></script> |
25 | 29 |
</head> |
26 | 30 |
|
@@ -9,7 +9,14 @@ window.ionic.Platform.ready(function() { |
||
9 | 9 |
angular.bootstrap(document, ['avalanche3mobile']); |
10 | 10 |
}); |
11 | 11 |
|
12 |
-angular.module('avalanche3mobile', ['ionic', 'ngCordova', 'avalanche3mobile.controllers', 'avalanche3mobile.missionData']) |
|
12 |
+angular.module('avalanche3mobile', [ |
|
13 |
+ 'ionic', |
|
14 |
+ 'ngCordova', |
|
15 |
+ 'avalanche3mobile.controllers', |
|
16 |
+ 'avalanche3mobile.missionData', |
|
17 |
+ 'avalanche3mobile.LoginCtrl', |
|
18 |
+ 'avalancheServices.Oauth' |
|
19 |
+]) |
|
13 | 20 |
|
14 | 21 |
.run(function($ionicPlatform) { |
15 | 22 |
$ionicPlatform.ready(function() { |
@@ -36,11 +43,30 @@ angular.module('avalanche3mobile', ['ionic', 'ngCordova', 'avalanche3mobile.cont |
||
36 | 43 |
controller: 'AppCtrl' |
37 | 44 |
}) |
38 | 45 |
|
46 |
+ .state('simple', { |
|
47 |
+ url: "/simple", |
|
48 |
+ abstract: true, |
|
49 |
+ templateUrl: "templates/simple.html", |
|
50 |
+ controller: 'AppCtrl' |
|
51 |
+ }) |
|
52 |
+ |
|
53 |
+ .state('simple.login', { |
|
54 |
+ url: "/login", |
|
55 |
+ views: { |
|
56 |
+ 'menuContent': { |
|
57 |
+ templateUrl: "templates/login.html", |
|
58 |
+ controller: 'LoginCtrl' |
|
59 |
+ } |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ }) |
|
63 |
+ |
|
39 | 64 |
.state('app.search', { |
40 | 65 |
url: "/search", |
41 | 66 |
views: { |
42 | 67 |
'menuContent': { |
43 |
- templateUrl: "templates/search.html" |
|
68 |
+ templateUrl: "templates/search.html", |
|
69 |
+ controller: 'MissionBriefingCtrl' |
|
44 | 70 |
} |
45 | 71 |
} |
46 | 72 |
}) |
@@ -122,5 +148,5 @@ angular.module('avalanche3mobile', ['ionic', 'ngCordova', 'avalanche3mobile.cont |
||
122 | 148 |
} |
123 | 149 |
}) |
124 | 150 |
// if none of the above states are matched, use this as the fallback |
125 |
- $urlRouterProvider.otherwise('/app/playlists'); |
|
151 |
+ $urlRouterProvider.otherwise('/simple/login'); |
|
126 | 152 |
}); |
@@ -2,6 +2,8 @@ angular.module('avalanche3mobile.controllers', []) |
||
2 | 2 |
|
3 | 3 |
.controller('AppCtrl', function($scope, $rootScope, $location, $ionicModal, $timeout, missionData, $ionicSideMenuDelegate, $cordovaStatusbar) { |
4 | 4 |
|
5 |
+ |
|
6 |
+ |
|
5 | 7 |
// With the new view caching in Ionic, Controllers are only called |
6 | 8 |
// when they are recreated or on app start, instead of every page change. |
7 | 9 |
// To listen for when this page is active (for example, to refresh data), |
@@ -0,0 +1,50 @@ |
||
1 |
+angular.module('avalanche3mobile.LoginCtrl', ['avalancheServices']) |
|
2 |
+ |
|
3 |
+ .controller('LoginCtrl', ['$scope', '$rootScope', '$location', '$ionicModal', '$timeout', '$ionicSideMenuDelegate', '$cordovaStatusbar', 'OAuthService', '$state', function($scope, $rootScope, $location, $ionicModal, $timeout, $ionicSideMenuDelegate, $cordovaStatusbar, OAuthService, $state) { |
|
4 |
+ |
|
5 |
+ // Initialize variables |
|
6 |
+ $scope.login = { email : "", password: ""}; |
|
7 |
+ |
|
8 |
+ $ionicModal.fromTemplateUrl('templates/modals/login.html', { |
|
9 |
+ scope: $scope, |
|
10 |
+ animation: 'slide-in-up' |
|
11 |
+ }).then(function(modal) { |
|
12 |
+ $scope.modal = modal; |
|
13 |
+ }); |
|
14 |
+ $scope.openLogin = function() { |
|
15 |
+ $scope.modal.show(); |
|
16 |
+ }; |
|
17 |
+ $scope.closeLogin = function() { |
|
18 |
+ $scope.modal.hide(); |
|
19 |
+ }; |
|
20 |
+ //Cleanup the modal when we're done with it! |
|
21 |
+ $scope.$on('$destroy', function() { |
|
22 |
+ $scope.modal.remove(); |
|
23 |
+ }); |
|
24 |
+ // Execute action on hide modal |
|
25 |
+ $scope.$on('modal.hidden', function() { |
|
26 |
+ // Execute action |
|
27 |
+ }); |
|
28 |
+ // Execute action on remove modal |
|
29 |
+ $scope.$on('modal.removed', function() { |
|
30 |
+ // Execute action |
|
31 |
+ }); |
|
32 |
+ |
|
33 |
+ $scope.authorizeUser = function(){ |
|
34 |
+ console.log("Authorizing user..."); |
|
35 |
+ OAuthService.authorizeUser($scope.login.email, $scope.login.password); |
|
36 |
+ } |
|
37 |
+ |
|
38 |
+ $rootScope.$on('auth:success', function() { |
|
39 |
+ if(!$scope.$$phase) { |
|
40 |
+ $scope.$apply(function(){ |
|
41 |
+ $scope.modal.hide(); |
|
42 |
+ $state.go("app.search"); |
|
43 |
+ }); |
|
44 |
+ } else { |
|
45 |
+ $scope.modal.hide(); |
|
46 |
+ $state.go("app.search"); |
|
47 |
+ } |
|
48 |
+ }); |
|
49 |
+ |
|
50 |
+ }]); |
@@ -0,0 +1,70 @@ |
||
1 |
+angular.module('avalancheServices', []) |
|
2 |
+.service('DataService', [ '$rootScope', '$http', function($rootScope, $http) { |
|
3 |
+ var response = {}; |
|
4 |
+ |
|
5 |
+ // GET |
|
6 |
+ this.get = function(url, inputs, token){ |
|
7 |
+ console.log("Requesting data from " + url); |
|
8 |
+ console.log(inputs); |
|
9 |
+ console.log(token); |
|
10 |
+ $http({ |
|
11 |
+ method: 'GET', |
|
12 |
+ url: url, |
|
13 |
+ headers: { 'Authorization' : "Bearer " + token }, |
|
14 |
+ params: inputs |
|
15 |
+ }).then(function(data, status, headers, config) { |
|
16 |
+ console.log("GET Request SUCCESSFULL") |
|
17 |
+ response.data = data.data; |
|
18 |
+ response.status = data.status; |
|
19 |
+ response.headers = data.headers; |
|
20 |
+ response.config = data.config; |
|
21 |
+ console.log(response) |
|
22 |
+ $rootScope.$broadcast('get-data:finished'); |
|
23 |
+ }, |
|
24 |
+ function(data, status) { |
|
25 |
+ console.log("GET Request FAILED") |
|
26 |
+ response.data = data.data; |
|
27 |
+ response.status = data.status; |
|
28 |
+ response.headers = data.headers; |
|
29 |
+ response.config = data.config; |
|
30 |
+ console.log(response) |
|
31 |
+ $rootScope.$broadcast('get-data:finished'); |
|
32 |
+ }); |
|
33 |
+ } |
|
34 |
+ |
|
35 |
+ // POST |
|
36 |
+ this.post = function(url, inputs, token){ |
|
37 |
+ console.log("Posting data to " + url); |
|
38 |
+ console.log(inputs); |
|
39 |
+ console.log(token); |
|
40 |
+ $http({ |
|
41 |
+ method: 'POST', |
|
42 |
+ url: url, |
|
43 |
+ headers: { 'Authorization' : "Bearer " + token }, |
|
44 |
+ params: inputs |
|
45 |
+ }).then(function(data, status, headers, config) { |
|
46 |
+ console.log("POST Request SUCCESSFULL") |
|
47 |
+ response.data = data.data; |
|
48 |
+ response.status = data.status; |
|
49 |
+ response.headers = data.headers; |
|
50 |
+ response.config = data.config; |
|
51 |
+ console.log(response) |
|
52 |
+ $rootScope.$broadcast('get-data:finished'); |
|
53 |
+ }, |
|
54 |
+ function(data, status) { |
|
55 |
+ console.log("POST Request FAILED") |
|
56 |
+ response.data = data.data; |
|
57 |
+ response.status = data.status; |
|
58 |
+ response.headers = data.headers; |
|
59 |
+ response.config = data.config; |
|
60 |
+ console.log(response) |
|
61 |
+ $rootScope.$broadcast('get-data:finished'); |
|
62 |
+ }); |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ // RESPONSE |
|
66 |
+ this.getResponse = function() { |
|
67 |
+ return response; |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+}]) |
@@ -0,0 +1,52 @@ |
||
1 |
+angular.module('avalancheServices.Oauth', []) |
|
2 |
+.service('OAuthService', [ '$rootScope', '$http', '$location', function($rootScope, $http, $location) { |
|
3 |
+ var code = {}; |
|
4 |
+ //var token = $cookies.get('avalanche_docs_token'); |
|
5 |
+ var token = ""; |
|
6 |
+ |
|
7 |
+ this.authorizeApplication = function(code){ |
|
8 |
+ $http({ |
|
9 |
+ method: 'POST', |
|
10 |
+ url: 'http://localhost:5000/oauth/token?client_id=d514f58c234d69ce1405f00dbef842bd785c09201b35a746d87306f5e69fd02b&client_secret=de63eb190485179d713df3e15339eb618e78e94ab96185621112dd0e5215997c&grant_type=authorization_code&redirect_uri=http://localhost:9000/&code=' + code |
|
11 |
+ }).then(function(data) { |
|
12 |
+ token = data.data.access_token; |
|
13 |
+ //$cookies.put('avalanche_docs_token', token); |
|
14 |
+ console.log("Application Authorization Flow SUCCESSFULL") |
|
15 |
+ console.log(data.data); |
|
16 |
+ $rootScope.$broadcast('auth:success'); |
|
17 |
+ }, |
|
18 |
+ function(data) { |
|
19 |
+ console.log("Application Authorization Flow FAILED") |
|
20 |
+ console.log(data); |
|
21 |
+ $rootScope.$broadcast('auth:failed'); |
|
22 |
+ }); |
|
23 |
+ } |
|
24 |
+ |
|
25 |
+ this.authorizeUser = function(username, password){ |
|
26 |
+ $http({ |
|
27 |
+ method: 'POST', |
|
28 |
+ url: 'http://localhost:5000/oauth/token', |
|
29 |
+ params: { |
|
30 |
+ "grant_type" : "password", |
|
31 |
+ "username" : username, |
|
32 |
+ "password" : password |
|
33 |
+ } |
|
34 |
+ }).then(function(data) { |
|
35 |
+ token = data.data.access_token; |
|
36 |
+ //$cookies.put('avalanche_docs_token', token); |
|
37 |
+ console.log("Resource Owner Password Credentials flow SUCCESSFULL") |
|
38 |
+ console.log(data.data); |
|
39 |
+ $rootScope.$broadcast('auth:success'); |
|
40 |
+ }, |
|
41 |
+ function(data) { |
|
42 |
+ console.log("Resource Owner Password Credentials flow FAILED") |
|
43 |
+ console.log(data); |
|
44 |
+ $rootScope.$broadcast('auth:failed'); |
|
45 |
+ }); |
|
46 |
+ } |
|
47 |
+ |
|
48 |
+ this.getToken = function() { |
|
49 |
+ return token; |
|
50 |
+ } |
|
51 |
+ |
|
52 |
+}]) |
@@ -0,0 +1,37 @@ |
||
1 |
+angular.module('avalancheServices', []) |
|
2 |
+.factory('RealtimeService', [ '$rootScope', '$http', function($rootScope, $http) { |
|
3 |
+ var FayeServerURL = 'https://avalanche-realtime.herokuapp.com/faye' |
|
4 |
+ |
|
5 |
+ var client = new Faye.Client(FayeServerURL); |
|
6 |
+ |
|
7 |
+ client.on('transport:down', function() { |
|
8 |
+ console.log("offline"); |
|
9 |
+ $rootScope.$broadcast('realtime:offline'); |
|
10 |
+ }); |
|
11 |
+ |
|
12 |
+ client.on('transport:up', function() { |
|
13 |
+ console.log("online"); |
|
14 |
+ $rootScope.$broadcast('realtime:online'); |
|
15 |
+ }); |
|
16 |
+ |
|
17 |
+ return { |
|
18 |
+ publish: function(channel, message) { |
|
19 |
+ client.publish(channel, message); |
|
20 |
+ }, |
|
21 |
+ |
|
22 |
+ subscribe: function(channel, callback) { |
|
23 |
+ client.subscribe(channel, callback).then(function() { |
|
24 |
+ console.log("subscribing to " + channel) |
|
25 |
+ }); |
|
26 |
+ }, |
|
27 |
+ disconect: function() { |
|
28 |
+ console.log("Disconecting...") |
|
29 |
+ client.disconnect(); |
|
30 |
+ $rootScope.$broadcast('realtime:offline'); |
|
31 |
+ }, |
|
32 |
+ connect: function() { |
|
33 |
+ client = new Faye.Client(FayeServerURL); |
|
34 |
+ $rootScope.$broadcast('realtime:online'); |
|
35 |
+ } |
|
36 |
+ } |
|
37 |
+}]); |
@@ -1,25 +1,10 @@ |
||
1 |
-<ion-modal-view> |
|
2 |
- <ion-header-bar> |
|
3 |
- <h1 class="title">Login</h1> |
|
4 |
- <div class="buttons"> |
|
5 |
- <button class="button button-clear" ng-click="closeLogin()">Close</button> |
|
6 |
- </div> |
|
7 |
- </ion-header-bar> |
|
8 |
- <ion-content> |
|
9 |
- <form ng-submit="doLogin()"> |
|
10 |
- <div class="list"> |
|
11 |
- <label class="item item-input"> |
|
12 |
- <span class="input-label">Username</span> |
|
13 |
- <input type="text" ng-model="loginData.username"> |
|
14 |
- </label> |
|
15 |
- <label class="item item-input"> |
|
16 |
- <span class="input-label">Password</span> |
|
17 |
- <input type="password" ng-model="loginData.password"> |
|
18 |
- </label> |
|
19 |
- <label class="item"> |
|
20 |
- <button class="button button-block button-positive" type="submit">Log in</button> |
|
21 |
- </label> |
|
22 |
- </div> |
|
23 |
- </form> |
|
24 |
- </ion-content> |
|
25 |
-</ion-modal-view> |
|
1 |
+<ion-view name="login" style="background-image: url('img/mount-everest.jpg')"> |
|
2 |
+ <p style="text-align: center; margin-top: 250px"> |
|
3 |
+ <button class="button button-outline button-light" ng-click="openLogin()" style="margin-right:5px;"> |
|
4 |
+ Log in |
|
5 |
+ </button> |
|
6 |
+ <button class="button button-outline button-light" ng-click="openLogin()" style="margin-left:5px;"> |
|
7 |
+ Sign up |
|
8 |
+ </button> |
|
9 |
+ </p> |
|
10 |
+</ion-view> |
@@ -0,0 +1,25 @@ |
||
1 |
+<ion-modal-view> |
|
2 |
+ <ion-header-bar> |
|
3 |
+ <h1 class="title">Login</h1> |
|
4 |
+ <div class="buttons"> |
|
5 |
+ <button class="button button-clear" ng-click="closeLogin()">Close</button> |
|
6 |
+ </div> |
|
7 |
+ </ion-header-bar> |
|
8 |
+ <ion-content> |
|
9 |
+ <form ng-submit="doLogin()"> |
|
10 |
+ <div class="list"> |
|
11 |
+ <label class="item item-input"> |
|
12 |
+ <span class="input-label">Email</span> |
|
13 |
+ <input type="text" ng-model="login.email"> |
|
14 |
+ </label> |
|
15 |
+ <label class="item item-input"> |
|
16 |
+ <span class="input-label">Password</span> |
|
17 |
+ <input type="password" ng-model="login.password"> |
|
18 |
+ </label> |
|
19 |
+ <label class="item"> |
|
20 |
+ <button class="button button-block button-positive" type="submit" ng-click="authorizeUser()">Log in</button> |
|
21 |
+ </label> |
|
22 |
+ </div> |
|
23 |
+ </form> |
|
24 |
+ </ion-content> |
|
25 |
+</ion-modal-view> |
@@ -0,0 +1 @@ |
||
1 |
+<ion-nav-view name="menuContent"></ion-nav-view> |